package com.future.service.Impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.future.allUtils.utils.SecurityUtils;
import com.future.allUtils.enums.TargetTypeEnum;
import com.future.domain.Article;
import com.future.domain.Comment;
import com.future.domain.MediaResource;
import com.future.domain.Result;
import com.future.domain.DTO.PageDTO;
import com.future.domain.DTO.CommentDTO;
import com.future.domain.vo.CommentVO;
import com.future.mapper.ArticleMapper;
import com.future.mapper.CommentMapper;
import com.future.mapper.MediaResourceMapper;
import com.future.mapper.NotificationMapper;
import com.future.service.CommentService;
import com.future.service.NotificationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class CommentServiceImpl implements CommentService {

    @Autowired
    private CommentMapper commentMapper;
    @Autowired
    private NotificationService notificationService;
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private MediaResourceMapper mediaResourceMapper;
    @Override
    public Result addComment(CommentDTO commentDTO) {
        // 检查评论内容内容是否为空
        if (commentDTO.getContent() == null || commentDTO.getContent().trim().isEmpty()) {
            return Result.fail("评论内容不能为空");
        }

        // 检查父评论是否存在（如果parentId不为0）
        if (commentDTO.getParentId() != 0) {
            Comment parentComment = commentMapper.selectById(commentDTO.getParentId());
            if (parentComment == null) {
                return Result.fail("父评论不存在");
            }
        }

        // 检查目标ID和类型是否存在
        if (commentDTO.getTargetId() == null) {
            return Result.fail("目标ID不能为空");
        }
        if (commentDTO.getTargetType() == null) {
            return Result.fail("目标类型不能为空");
        }

        // 转换DTO到实体类
        Comment comment = new Comment();
        comment.setTargetId(commentDTO.getTargetId());
        comment.setTargetType(commentDTO.getTargetType());
        comment.setParentId(commentDTO.getParentId());
        comment.setContent(commentDTO.getContent());

        // 设置创建时间和评论者id
        comment.setCreatedAt(LocalDateTime.now());
        comment.setUserId(SecurityUtils.getCurrentUserId());
        int result = commentMapper.insert(comment);
        if(result>0)
        {
            // 情况1：当前评论是回复（存在父评论）
            if(comment.getParentId()!=0)
            {
                // 发送通知：告知父评论作者“有人回复了你的评论”
                // 参数说明：
                // 1. parentComment.getUserId()：被通知人ID（父评论作者）
                // 2. comment.getId()：当前评论ID（关联的评论）
                // 3. "回复了你的评论"：通知内容
                Comment comment1 = commentMapper.selectById(comment.getParentId());
                notificationService.sendComment(TargetTypeEnum.COMMENT.getTargetTypeId(),comment1.getUserId(),comment.getId(),"回复了你的评论");
            }else{
                // 情况2：当前评论是顶级评论（非回复），根据被评论对象类型发送通知
                // 根据目标类型发送不同的通知
                if (comment.getTargetType().equals(TargetTypeEnum.ARTICLE.getTargetTypeId())) { // 文章
                    Article article = articleMapper.selectById(comment.getTargetId());
                    if (article != null) {
                        notificationService.sendComment(TargetTypeEnum.ARTICLE.getTargetTypeId(),article.getAuthorId(), comment.getId(), "评论了你的文章");
                    }
                } else if (comment.getTargetType().equals(TargetTypeEnum.MEDIA_RESOURCE.getTargetTypeId())) { // 媒体资源
                     MediaResource mediaResource = mediaResourceMapper.selectById(comment.getTargetId());
                     if (mediaResource != null) {
                         notificationService.sendComment(TargetTypeEnum.MEDIA_RESOURCE.getTargetTypeId(),mediaResource.getUploaderId(), comment.getId(), "评论了你的媒体资源");
                     }
                }
                // 可添加其他类型
            }
        }
        return result > 0 ? Result.ok("评论添加成功") : Result.fail("评论添加失败");
    }

    @Override
    public Result getCommentsByTarget(Long targetId, Integer targetType, int pageNum, int pageSize) {
        // 参数校验
        if (pageNum < 1) pageNum = 1;
        if (pageSize < 1) pageSize = 10;
        if (targetId == null) {
            return Result.fail("目标ID不能为空");
        }
        if (targetType == null) {
            return Result.fail("目标类型不能为空");
        }

        // 1. 创建MyBatis-Plus分页对象
        Page<CommentVO> page = new Page<>(pageNum, pageSize);

        // 2. 调用Mapper层方法（自动分页）
        Page<CommentVO> commentPage = commentMapper.getCommentsByTarget(page, targetId, targetType);
        for(CommentVO commentVO:commentPage.getRecords()){
            commentVO.setUserIdStr(commentVO.getUserId().toString());
        }

        // 3. 获取所有评论构建树形结构
        List<CommentVO> allComments = commentPage.getRecords();
        List<CommentVO> fullTree = buildCommentTree(allComments);

        // 4. 提取一级评论（parentId=0）
        List<CommentVO> firstLevelComments = fullTree.stream()
                .filter(vo -> vo.getParentId() == 0L)
                .collect(Collectors.toList());

        // 5. 转换为自定义PageDTO
        PageDTO<CommentVO> pageDTO = new PageDTO<CommentVO>()
                .setRows(firstLevelComments)
                .setTotal(commentPage.getTotal())
                .setTotalPage(commentPage.getPages());

        return Result.ok(pageDTO);
    }

    @Override
    public Result getTopLevelComments(Long targetId, Integer targetType, int pageNum, int pageSize) {
        // 参数校验
        if (pageNum < 1) pageNum = 1;
        if (pageSize < 1) pageSize = 10;
        if (targetId == null) {
            return Result.fail("目标ID不能为空");
        }
        if (targetType == null) {
            return Result.fail("目标类型不能为空");
        }

        // 1. 创建MyBatis-Plus分页对象
        Page<CommentVO> page = new Page<>(pageNum, pageSize);

        // 2. 调用Mapper层方法
        Page<CommentVO> commentPage = commentMapper.getTopLevelComments(page, targetId, targetType);
        for(CommentVO commentVO:commentPage.getRecords()){
            commentVO.setUserIdStr(commentVO.getUserId().toString());
        }

        // 3. 转换为自定义PageDTO
        PageDTO<CommentVO> pageDTO = new PageDTO<CommentVO>()
                .setRows(commentPage.getRecords())
                .setTotal(commentPage.getTotal())
                .setTotalPage(commentPage.getPages());

        return Result.ok(pageDTO);
    }

    @Override
    public Result getCommentsByArticle(Long articleId, int pageNum, int pageSize) {
        // 保持向后兼容性，调用新方法并设置目标类型为1（文章）
        return getCommentsByTarget(articleId, TargetTypeEnum.ARTICLE.getTargetTypeId(), pageNum, pageSize);
    }

    @Override
    public Result getChildComments(Long parentId, int pageNum, int pageSize,Long targetTypeId) {
        // 参数校验
        if (pageNum < 1) pageNum = 1;
        if (pageSize < 1) pageSize = 5;
        if (parentId == null) {
            return Result.fail("父评论ID不能为空");
        }

        // 1. 创建分页对象
        Page<CommentVO> page = new Page<>(pageNum, pageSize);

        // 2. 调用mapper方法自动分页
        Page<CommentVO> childPage = commentMapper.getChildComments(page, parentId,targetTypeId);
        for(CommentVO commentVO:childPage.getRecords()){
            commentVO.setUserIdStr(commentVO.getUserId().toString());
        }
        // 3. 转换为PageDTO返回
        return Result.ok(PageDTO.pageConvert(childPage));
    }

    @Override
    @Transactional
    public Result deleteComment(Long commentId) {
        deleteCommentAndChildren(commentId);
        return Result.ok("评论删除成功");
    }

    @Override
    public Result getTotalCommentsReceived(Long userId) {
        // 参数校验
        if (userId == null) {
            return Result.fail("用户ID不能为空");
        }
        
        // 调用Mapper层方法查询收到的评论数
        Long totalComments = commentMapper.selectTotalCommentsReceived(userId);
        
        return Result.ok(totalComments);
    }

    private void deleteCommentAndChildren(Long commentId) {
        // 查询子评论
        List<Comment> childComments = commentMapper.selectChildComments(commentId);
        for (Comment child : childComments) {
            deleteCommentAndChildren(child.getId());
        }
        commentMapper.deleteById(commentId);
    }

    // 基于CommentVO构建评论树
    private List<CommentVO> buildCommentTree(List<CommentVO> allComments) {
        // 按父ID分组
        Map<Long, List<CommentVO>> commentMap = allComments.stream()
                .collect(Collectors.groupingBy(CommentVO::getParentId));

        // 获取所有评论ID集合
        Set<Long> commentIds = allComments.stream()
                .map(CommentVO::getId)
                .collect(Collectors.toSet());

        // 构建顶级评论（包括孤儿评论）
        List<CommentVO> topLevelComments = new ArrayList<>();
        for (CommentVO vo : allComments) {
            Long parentId = vo.getParentId();
            // 满足以下任一条件即为顶级评论：
            // 1. 无父评论（parentId=0）
            // 2. 父评论不在当前查询结果中（孤儿评论）
            if (parentId == 0 || !commentIds.contains(parentId)) {
                topLevelComments.add(vo);
            }
        }

        // 递归构建树形结构
        for (CommentVO topVo : topLevelComments) {
            buildChildrenRecursive(topVo, commentMap);
        }

        return topLevelComments;
    }
    
    private void buildChildrenRecursive(CommentVO parentVo, Map<Long, List<CommentVO>> commentMap) {
        Long parentId = parentVo.getId();
        List<CommentVO> children = commentMap.getOrDefault(parentId, Collections.emptyList());

        // 设置子评论（即使为空，也显式设置为null或空列表）
        parentVo.setChildren(children);

        // 递归处理子评论
        for (CommentVO childVo : children) {
            buildChildrenRecursive(childVo, commentMap);
        }
    }

//    // 递归为父评论添加子评论
//    private void buildChildren(CommentVO parentVo, Map<Long, List<CommentVO>> commentMap) {
//        Long parentId = parentVo.getId();
//        List<CommentVO> children = commentMap.getOrDefault(parentId, Collections.emptyList());
//
//        if (!children.isEmpty()) {
//            parentVo.setChildren(children); // 直接设置子评论列表
//            // 递归处理子评论的子评论
//            children.forEach(childVo -> buildChildren(childVo, commentMap));
//        }
//    }
}
